tpu-inference/k8s: MultiKueue GKE infrastructure for TPU CI - #438
Draft
theminghuang wants to merge 1 commit into
Draft
tpu-inference/k8s: MultiKueue GKE infrastructure for TPU CI#438theminghuang wants to merge 1 commit into
theminghuang wants to merge 1 commit into
Conversation
Collaborator
Author
|
This change is part of the following stack: Change managed by git-spice. |
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
6 times, most recently
from
July 28, 2026 22:35
c7e95c0 to
591665f
Compare
theminghuang
marked this pull request as draft
July 30, 2026 17:43
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
10 times, most recently
from
August 11, 2026 05:03
e1a1d53 to
5bb73df
Compare
This was referenced Aug 11, 2026
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
6 times, most recently
from
August 11, 2026 23:30
603f6d1 to
d95046f
Compare
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
from
August 14, 2026 05:01
6cd16c1 to
3255eb4
Compare
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
from
August 18, 2026 05:55
9cef2c8 to
c4f616a
Compare
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
3 times, most recently
from
August 19, 2026 00:35
3d1f0cd to
128ca12
Compare
Terraform, Kueue manifest templates and a generator for running TPU CI on GKE: one CPU-only manager cluster running the Buildkite agent-stack-k8s controller and Kueue, and one worker cluster per region with TPU node pools that autoscale from the reservation, joined by MultiKueue over Connect Gateway. One input, prod.auto.tfvars: a map of worker clusters, each with its TPU pools. The pool key is the profile name a pipeline passes and, verbatim, the node pool, the ClusterQueue and the LocalQueue. terraform apply builds the clusters, node pools (reservation affinity, image streaming, TPU taint; a pool with hosts > 1 is a multi-host slice pool with a placement policy carrying the topology, one node per host, scaled atomically), the regional cache buckets with their PersistentVolumes and claims, IAM (dedicated node service accounts, Workload Identity for the workload service account and the Kueue controllers, cross-project Artifact Registry read), External Secrets, the JobSet operator and Kueue itself. scripts/generate_manifests.py renders everything Kubernetes-side from the same file - cohorts and ResourceFlavors per accelerator, ClusterQueues and LocalQueues per pool (a worker's quota is its own capacity, the manager's is the sum over the workers that have the profile), MultiKueue fleet and AdmissionChecks, per-worker RBAC, the workload ServiceAccount and the cache volumes - into generated/, which is committed so a diff after an unrelated change means drift. Only google.com/tpu is under Kueue quota; cpu and memory are ignored by admission (quotaCheckStrategy: IgnoreUndeclared) and left to the scheduler. The v6e worker in southamerica-west1-a carries two profiles on one 18-chip reservation: v6e-1-1x1 (ten chips, two kept warm) and v6e-8-2x4 (one node). Validated end to end from tpu-inference: five full per-push suites (kube-dev builds 255-260), and a four-host JobSet slice on this infrastructure (build 272) - the multi-host pool support is kept; the pool itself is not declared. scripts/deploy_manifests.sh applies that committed output rather than regenerating over it, so a shared cluster only ever sees manifests that went through review; it renders into a scratch directory first purely to prove the committed ones are current, and refuses to apply if they are not. Each cluster is addressed by an explicit --context captured from its own get-credentials, in a kubeconfig of the script's own, and every apply is preceded by a kubectl diff and a confirmation. It still only creates and updates - a queue dropped from the tfvars stays in the cluster until someone removes it. The Kueue controller Deployment is patched from kueue.tf rather than from that script. The Deployment is the chart's, so any release that re-renders it - a kueue_version bump, an edit to manager-config.yaml - drops the gcp-auth-plugin initContainer and the manager silently loses the credentials it dispatches to workers with. Keyed on the release revision, the patch goes back on whenever that happens; chart 0.19.0 exposes no values that would carry it. initial_node_count is ignored on the worker TPU pools, as it already was on the manager's system pool. It is a create-time field GKE reports as whatever the pool has scaled to since, so left tracked it drifts on its own and any edit to min_nodes reads as a change to it - forcing the pool to be destroyed and rebuilt when all that was wanted is a new autoscaling floor.
theminghuang
force-pushed
the
feature/tpu-multikueue-k8s-infra
branch
from
August 26, 2026 23:09
128ca12 to
ac00311
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Terraform, Kueue manifest templates and a generator for running TPU CI on GKE. First of two stacked PRs: this one is the infrastructure a Buildkite step needs to land on a TPU node pool; #467 adds the launcher that turns a step into a workload. The pipeline that uses both is tpu-inference#3377.
Shape
cloud-ullm-inference-ci-cd, us-central1) running the Buildkite agent-stack-k8s controller on a single queue, Kueue, and the JobSet operator.southamerica-west1-aincloud-tpu-inference-test) with TPU node pools that autoscale from the reservation, joined to the manager by MultiKueue over Connect Gateway.One input
prod.auto.tfvarsdeclares the manager and a map of worker clusters, each with its TPU pools. The pool key is the profile name a pipeline names and, verbatim, the node pool, the ClusterQueue and the LocalQueue. Two consumers:terraform apply- clusters, node pools (reservation affinity, image streaming, TPU taint; a pool withhosts > 1is a multi-host slice pool with a placement policy carrying the topology, one node per host, scaled atomically), buckets and PVs, IAM (dedicated node SAs, Workload Identity for the workload SA and the Kueue controllers, cross-project Artifact Registry read), External Secrets, JobSet, Kueue.scripts/generate_manifests.py- cohorts and ResourceFlavors per accelerator, ClusterQueues and LocalQueues per pool (a worker's quota is its own capacity; the manager's is the sum over the workers that have the profile), MultiKueue fleet and AdmissionChecks, per-worker RBAC, the workload ServiceAccount, the cache volumes. Rendered intogenerated/, which is committed: a diff after an unrelated change means drift.Only
google.com/tpuis under Kueue quota; cpu and memory are ignored by admission (quotaCheckStrategy: IgnoreUndeclared) and left to the scheduler.The v6e worker
Two profiles on one 18-chip reservation:
v6e-1-1x1(ten chips, two nodes kept warm) andv6e-8-2x4(one node). Multi-host slice pools (hosts > 1: placement policy with the topology, one node per host, atomic scaling, whole-slice validation) are supported but none is declared; a four-hostct6e-standard-4t4x4 slice was run on this infrastructure during validation and is left out until multi-host steps join the suite.Verified
From tpu-inference: five consecutive full per-push suites (kube-dev builds 255-260, 16/16 steps), and separately a four-host JobSet slice built from zero, admitted as one workload, running JAX and vLLM TP=16 across hosts (build 272).